#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
#define pi acos(-1.0)
#define e exp(1.0)
const int maxn=1e3+7;
char mp[maxn][maxn];
int col[maxn],row[maxn];
bool vis[maxn][maxn];
int N,M;
int dir[4][2]={1,0,-1,0,0,-1,0,1};
//通过分析知道，将所有的#都填上南极磁铁对结果是没有影响的，如果填上之后不满足条件1 的话可以贪心
//的填充#，之后判断是否满足条件2 和3，如果不满足答案就是-1,满足答案就是联通块的个数  
//找联通的个数 
void DFS(int x,int y)
{
	vis[x][y]=1;
	for(int i=0;i<4;i++){
		int X=x+dir[i][0];
		int Y=y+dir[i][1];
		if(X>=1&&X<=N&&Y>=1&&Y<=M&&!vis[X][Y]&&mp[X][Y]=='#')
		DFS(X,Y);
	}
	return ;
}
void Solve()
{
	int i,j;
	cin>>N>>M;
	memset(vis,0,sizeof(vis));
	for(i=1;i<=N;i++){
		cin>>(mp[i]+1);
		for(j=1;j<=M;j++){
			if(mp[i][j]=='#'){
				row[i]++;
				col[j]++;
			}
		} 
	}
	for(i=1;i<=N;i++){
		for(j=1;j<=M;j++){
			if(row[i]==0&&col[j]==0)
			vis[i][j]=1;
		}
	}
	for(i=1;i<=N;i++){//判断每一行是否满足条件1 2 3  
		int	cnt=0;
		for(j=1;j<=M;j++){
			if(vis[i][j]==1)
			cnt++;
		}
		cnt+=row[i];
		if(cnt==0){
		puts("-1");
		return ;
		} 
		cnt=row[i];
		for(j=1;j<=M;j++){
			if(mp[i][j]=='.'&&cnt&&cnt!=row[i]){
				puts("-1");
				return ;	
			}
			if(mp[i][j]=='#')
			cnt--;
		}
	}
	for(j=1;j<=M;j++){
		int cnt=0;
		for(i=1;i<=N;i++){
			if(vis[i][j]==1)
			cnt++;
		}
		cnt+=col[j];
		if(cnt==0){
			puts("-1");
			return ; 
		}
		cnt=col[j];
		for(i=1;i<=N;i++){
			if(mp[i][j]=='.'&&cnt&&cnt!=col[j]){
				puts("-1");
				return ;
			}
			if(mp[i][j]=='#')
			cnt--;
		}
	}
	memset(vis,0,sizeof(vis));
	int ans=0;
	for(i=1;i<=N;i++){
		for(j=1;j<=M;j++){
			if(!vis[i][j]&&mp[i][j]=='#'){
				DFS(i,j);
				ans++;			 
			}
		}
	}
	cout<<ans<<endl;
	return ;
}
int main()
{
//  freopen(".../.txt","w",stdout);
	ios::sync_with_stdio(false);
	Solve();
	return 0;
}
